package com.drd.dt.util;


import com.alibaba.fastjson.JSON;
import com.drd.dt.util.verify.BaseUtils;
import okhttp3.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.*;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;


/**
 * 获取第三方数据 工具类  HttpClient 连接池工具类
 */
public class HttpConnectionPoolUtil {
    private static Logger LOGGER = LoggerFactory.getLogger(HttpConnectionPoolUtil.class);

    private static PoolingHttpClientConnectionManager cm = null;

    static {
        getPoolingHttpClientConnectionManager();
    }

    //加载 PoolingHttpClientConnectionManager 连接池
    private static void getPoolingHttpClientConnectionManager() {
        LayeredConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            LOGGER.error("创建SSL连接失败");
        }
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(1200);
        cm.setDefaultMaxPerRoute(25);
    }

    //给出连接池对象
    public static PoolingHttpClientConnectionManager getHttpClientPooing() {
        return cm;
    }

    public static CloseableHttpClient getHttpClient() {
        if (cm == null) {
            getPoolingHttpClientConnectionManager();
        }
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .build();
        return httpClient;
    }

    /**
     * 设置信任自签名证书
     *
     * @param keyStorePath 密钥库路径
     * @param keyStorepass 密钥库密码
     * @return
     */
    private static SSLContext custom(String keyStorePath, String keyStorepass) {
        SSLContext sc = null;
        FileInputStream instream = null;
        KeyStore trustStore = null;
        try {
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            instream = new FileInputStream(new File(keyStorePath));
            trustStore.load(instream, keyStorepass.toCharArray());
            // 相信自己的CA和所有自签名的证书
            sc = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | KeyManagementException e) {
            e.printStackTrace();
        } finally {
            try {
                instream.close();
            } catch (IOException e) {
            }
        }
        return sc;
    }


    //GET 京东专用get
    public static String getJD(String urlStr) {
        String response = "";
        // 创建默认的httpClient实例
        CloseableHttpClient httpClient = HttpConnectionPoolUtil.getHttpClient();
        CloseableHttpResponse httpResponse = null;
        // 发送get请求
        try {
            // 用get方法发送http请求
            URL url = new URL(urlStr);
            URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
            HttpGet get = new HttpGet(uri);

            get.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setSocketTimeout(5000).build());
            get.setHeader("Content-type", "application/json");

            httpResponse = httpClient.execute(get);

            // response实体
            HttpEntity entity = httpResponse.getEntity();
            if (null != entity) {
                int statusCode = httpResponse.getStatusLine().getStatusCode();
                if (statusCode == HttpStatus.SC_OK) {
                    response = EntityUtils.toString(entity, "UTF-8");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    EntityUtils.consume(httpResponse.getEntity());
                    httpResponse.close();
                } catch (IOException e) {
                    LOGGER.error("关闭response失败", e);
                }
            }
        }
        return response;

    }


    //GET
    public static String get(String url) {
        String response = "";
        // 创建默认的httpClient实例
        CloseableHttpClient httpClient = HttpConnectionPoolUtil.getHttpClient();
        CloseableHttpResponse httpResponse = null;
        // 发送get请求
        try {
            // 用get方法发送http请求
            URIBuilder builder = new URIBuilder(url);
            HttpGet get = new HttpGet(builder.build());

            get.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setSocketTimeout(5000).build());
            get.setHeader("Content-type", "application/json");

            httpResponse = httpClient.execute(get);

            // response实体
            HttpEntity entity = httpResponse.getEntity();
            if (null != entity) {
                int statusCode = httpResponse.getStatusLine().getStatusCode();
                if (statusCode == HttpStatus.SC_OK) {
                    response = EntityUtils.toString(entity, "UTF-8");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    EntityUtils.consume(httpResponse.getEntity());
                    httpResponse.close();
                } catch (IOException e) {
                    LOGGER.error("关闭response失败", e);
                }
            }
        }
        return response;

    }

    /**
     * 高佣专用 POST
     */
    public static String postGY(String urlStr, StringBuffer body) {
        String result = null;
//        String urlString="http://v2.api.haodanku.com/ratesurl";
        InputStream is = null;
        String param = null;
//        StringBuilder sbParams=new StringBuilder();
//        sbParams.append("apikey");
//        sbParams.append("=");
//        sbParams.append("youfangou");
//        sbParams.append("&");
//        sbParams.append("itemid");
//        sbParams.append("=");
//        sbParams.append("573692914125");
//        sbParams.append("&");
//        sbParams.append("pid");
//        sbParams.append("=");
//        sbParams.append("mm_286230175_256450395_72327100467");
//        sbParams.append("&");
//        sbParams.append("tb_name");
//        sbParams.append("=");
//        sbParams.append("鼎荣达2721");
        try {
            URL url = new URL(urlStr);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//post请求需要设置DoOutput为true
            urlConnection.setDoOutput(true);
            urlConnection.setRequestMethod("POST");
//设置参数
            param = body.toString();
            urlConnection.getOutputStream().write(param.getBytes());
            urlConnection.getOutputStream().flush();
            urlConnection.setConnectTimeout(5 * 1000);
            urlConnection.setReadTimeout(5 * 1000);
//连接服务器
            urlConnection.connect();
            StringBuilder stringBuilder = new StringBuilder();
            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                is = urlConnection.getInputStream();
                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = is.read(buffer)) != -1) {
                    stringBuilder.append(new String(buffer, 0, len));
                }
                result = stringBuilder.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    //POST请求
    public static String post(String url, StringBuffer body) {
        // 创建默认的httpClient实例
        CloseableHttpClient httpClient = HttpConnectionPoolUtil.getHttpClient();
        CloseableHttpResponse httpResponse = null;
        String response = "";
        // 发送get请求
        try {
            HttpPost post = new HttpPost(url);
            StringEntity se = new StringEntity(body.toString(), "UTF-8");
            post.setEntity(se);

            //设置请求头(以及 超时时间)
            post.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setSocketTimeout(5000).build());
            post.setHeader("Content-type", "application/json");
            post.setHeader("Accept-Encoding", "gzip,deflate");

            httpResponse = httpClient.execute(post);
            HttpEntity entity = httpResponse.getEntity();
            if (null != entity) {
                int statusCode = httpResponse.getStatusLine().getStatusCode();
                if (statusCode == HttpStatus.SC_OK) {
                    response = EntityUtils.toString(entity);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    EntityUtils.consume(httpResponse.getEntity());
                    httpResponse.close();
                } catch (IOException e) {
                    LOGGER.error("关闭response失败", e);
                }
            }
            return response;
        }
    }

    public static String postCommandFromNet2(String httpurl,String  body) {
        String result = null;
        HttpURLConnection httpConn=null;
        try {
            URL url = new URL(httpurl);
            httpConn = (HttpURLConnection) url
                    .openConnection();
            httpConn.setDoInput(true);//
            httpConn.setDoOutput(true);//
            httpConn.setRequestProperty("Connection", "keep-alive");
            //将数据进行压缩
//            httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate");
            httpConn.setConnectTimeout(20000);
            httpConn.setReadTimeout(20000);
            httpConn.setUseCaches(false);//
            httpConn.setRequestMethod("POST");
            httpConn.connect();
            DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream());
            dos.write(body.getBytes("utf-8"));//code
            dos.flush();
            dos.close();
            int responseCode = httpConn.getResponseCode();
            if (responseCode == 200) {
                InputStream is = httpConn.getInputStream();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                int temp = 0;

                while ((temp = is.read()) != -1) {
                    bos.write(temp);

                }
                byte[] bsResult = bos.toByteArray();
                //解压缩
//                bsResult = unGZip(bsResult);
                result = new String(bsResult, "utf-8");
                bos.close();
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(httpConn!=null){
                httpConn.disconnect();
                httpConn=null;
            }
        }
        return result;
    }

    //解压缩
    public static byte[] unGZip(byte[] data) {
        byte[] b = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(data);
            GZIPInputStream gzip = new GZIPInputStream(bis);
            byte[] buf = new byte[1024];
            int num = -1;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while ((num = gzip.read(buf, 0, buf.length)) != -1) {
                baos.write(buf, 0, num);
            }
            b = baos.toByteArray();
            baos.flush();
            baos.close();
            gzip.close();
            bis.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return b;
    }

    public static String httpXML(String url, String xml) {
        String result = null;
        try {
            InputStream is = httpPostXML(url, xml);
            BufferedReader in = new BufferedReader(new InputStreamReader(is,"UTF-8"));
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = in.readLine()) != null) {
                buffer.append(line);
            }
            result = buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return result;
    }

    private static InputStream httpPostXML(String url, String xml) {
        InputStream is = null;
        PrintWriter out = null;
        try {
            URL u;
            u = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");
            conn.setConnectTimeout(20000);
            conn.setReadTimeout(50000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            OutputStreamWriter outWriter = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            out = new PrintWriter(outWriter);
            out.print(xml);
            out.flush();
            out.close();
            is = conn.getInputStream();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return is;
    }

}
